// File: jmcomic-core/src/main/java/dev/jukomu/common/util/net/CommonResponse.java
package dev.jukomu.common.util.net;

import dev.jukomu.common.util.json.AdvancedMap;
import dev.jukomu.common.util.json.JsonUtils;
import okhttp3.Response;
import okhttp3.ResponseBody;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

/**
 * 对OkHttp Response的通用封装，实现IResponse接口。
 */
public class CommonResponse implements IResponse {

    protected final Response rawResponse; // 原始OkHttp Response对象

    // 添加缓存字段
    private volatile byte[] cachedContent; // 使用volatile确保多线程可见性
    private final Object contentLock = new Object(); // 用于同步的锁对象

    public CommonResponse(Response rawResponse) {
        if (rawResponse == null) {
            throw new IllegalArgumentException("Raw OkHttp Response cannot be null.");
        }
        this.rawResponse = rawResponse;
    }

    @Override
    public int getHttpCode() {
        return rawResponse.code();
    }

    @Override
    public boolean isSuccess() {
        return rawResponse.isSuccessful(); // OkHttp's isSuccessful() checks 200-299 range
    }

    @Override
    public void requireSuccess() throws AssertionError {
        if (isNotSuccess()) {
            throw new AssertionError("Response is not successful. HTTP Code: " + getHttpCode() + ", URL: " + getUrl());
        }
    }

    @Override
    public String getText() {
        // 从缓存的字节数组中获取文本
        byte[] content = getContent();
        return new String(content, StandardCharsets.UTF_8);
    }

    @Override
    public String getUrl() {
        return rawResponse.request().url().toString();
    }

    @Override
    public Map<String, String> getHeaders() {
        return rawResponse.headers().toMultimap().entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> String.join("; ", entry.getValue()), // Join multiple values for same header key
                        (existing, replacement) -> existing, // Merge function for duplicate keys, keep existing
                        HashMap::new
                ));
    }

    @Override
    public byte[] getContent() {
        // 实现一次性读取和缓存
        if (cachedContent == null) {
            synchronized (contentLock) {
                // 双重检查锁定，防止多个线程同时读取
                if (cachedContent == null) {
                    try (ResponseBody body = rawResponse.body()) {
                        if (body != null) {
                            String s = getHeaders().get("content-encoding");
                            if (!Objects.equals(s, "gzip")) {
                                cachedContent = body.bytes(); // 读取并关闭响应体
                            } else {
                                byte[] decompressedBytes;
                                try (InputStream responseStream = body.byteStream()) {
                                    // 使用GZIPInputStream来包装响应的输入流
                                    try (GZIPInputStream gzipInputStream = new GZIPInputStream(responseStream)) {
                                        // 读取解压后的数据
                                        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                                        int n;
                                        byte[] data = new byte[1024];
                                        while ((n = gzipInputStream.read(data, 0, 1024)) != -1) {
                                            buffer.write(data, 0, n);
                                        }
                                        cachedContent = buffer.toByteArray();
                                    }
                                }
                            }
                        } else {
                            cachedContent = new byte[0];
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return cachedContent;
    }

    @Override
    public String getRedirectUrl() {
        String location = rawResponse.header("Location");
        return location != null ? location : "";
    }

    @Override
    public Map<String, Object> getJson() throws IOException {
        String text = getText();
        if (text == null || text.isEmpty()) {
            return Collections.emptyMap();
        }
        return JsonUtils.parseStringAsMap(text);
    }

    @Override
    public AdvancedMap getModel() throws IOException {
        return new AdvancedMap(getJson());
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getRawResponse() {
        return (T) rawResponse;
    }

    /**
     * 获取HTTP响应的重定向次数。
     *
     * @return 重定向次数
     */
    public int getRedirectCount() {
        return getRedirectCountRecursive(rawResponse);
    }

    // 辅助方法，递归计算重定向次数
    private int getRedirectCountRecursive(Response response) {
        Response prior = response.priorResponse();
        if (prior != null) {
            return 1 + getRedirectCountRecursive(prior);
        }
        return 0;
    }

    @Override
    public String toString() {
        return "CommonResponse{" +
                "httpCode=" + getHttpCode() +
                ", url='" + getUrl() + '\'' +
                ", success=" + isSuccess() +
                '}';
    }
}